package com.kris;

import java.io.FileOutputStream;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.WorkbookUtil;

/**
 * 当月节假日员工加班统计表
 *
 * @author Kris Zhang
 */
public class WeekendHolidayOverTimeReport extends Report {

    final String title = "节假日加班统计表";
    final String[] header = {"姓名", "加班日期", "时间点", "时长", "主要内容", "备注"};

    // 员工出勤记录
    Map<String, EmployeeAttendRecord> records;
    // 员工名单
    List<String> employeeList;
    // 指定的节假日
    List<Date> holidays;
    // 排除的周末
    List<Date> excludeHolidays;

    //此报表的文件名称
    String filename = null;
    String sheetName = null;

    WeekendHolidayOverTimeReport(String excelFilename,
            List<String> employeeList,
            Map<String, EmployeeAttendRecord> records,
            List<Date> holidays,
            List<Date> excludeHolidays) {
        this.filename = excelFilename;
        this.employeeList = employeeList;
        this.records = records;
        this.sheetName = "xx月加班";
        this.holidays = holidays;
        this.excludeHolidays = excludeHolidays;
    }

    @Override
    public void make() throws Exception {
        // 新建一个excel
        Workbook wb = new HSSFWorkbook();

        //工作簿
        String safeName = WorkbookUtil.createSafeSheetName(this.sheetName);
        Sheet sheet = wb.createSheet(safeName);

        // 建立第一个行， 把表的标题放到这里
        Row firstRow = sheet.createRow((short) 0);
        CellStyle titleStyle = wb.createCellStyle();
        titleStyle.setAlignment(HorizontalAlignment.CENTER); // 设置字体居中显示
        titleStyle.setFont(createFontArial18(wb));

        Cell titleCell = firstRow.createCell(0);
        titleCell.setCellValue(title);
        titleCell.setCellStyle(titleStyle);

        // 合并第一行表格
        sheet.addMergedRegion(new CellRangeAddress(
                0, //first row (0-based)
                0, //last row  (0-based)
                0, //first column (0-based)
                5 //last column  (0-based)
        ));

        // 建立表格样式, 设置背景颜色
        CellStyle headerStyle = wb.createCellStyle();
        headerStyle.setFillForegroundColor(IndexedColors.YELLOW.index);
        headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        headerStyle.setAlignment(HorizontalAlignment.CENTER); // 设置字体居中显示
        headerStyle.setFont(createFontArial14(wb));

        // 建立第2行, 设置表头
        Row secondRow = sheet.createRow((short) 1);
        for (int j = 0; j < header.length; j++) {
            Cell headerCell = secondRow.createCell(j);
            headerCell.setCellValue(header[j]);
            headerCell.setCellStyle(headerStyle);
        }

        // ---------------------------------------------
        //                表格数据
        // ---------------------------------------------
        // 表格数据格式
        CellStyle dataStyle = wb.createCellStyle();
        dataStyle.setFont(createFontArial12(wb));

        int rowIndex = 2; //员工数据开始的行数
        // 获取所有员工名单
        // 循环处理每个员工的时间
        for (int i = 0; i < employeeList.size(); i++) {
            String name = employeeList.get(i);

            // 获取此员工所有的加班信息记录
            EmployeeAttendRecord em = records.get(name);
            if (em == null) {
                // 忽略不存在考勤记录的员工
                continue;
            }

            List<EmployeeWorkTime> worktimes = em.getWorkTimeRecords();
            if (worktimes == null || worktimes.isEmpty()) {
                continue;
            }
            Collections.sort(worktimes, new EmployeeWorkTimeComparator());

            for (int k = 0; k < worktimes.size(); k++) {
                EmployeeWorkTime employeeWorkTime = worktimes.get(k);

                if (!DateUtil.isWeekendOrHoliday(employeeWorkTime.getBeginTime(),
                        this.holidays,
                        this.excludeHolidays)) {
                    // 只统计周末和节假日
                    continue;
                }

                double overtime = calculateHolidayWorkOverTime(
                        employeeWorkTime.getBeginTime(),
                        employeeWorkTime.getEndTime());
                if (overtime <= 0) {
                    // 加班时长为0的，不显示到报表中
                    continue;
                }

                // 建立一个行
                Row row = sheet.createRow(rowIndex);
                Cell cell0 = row.createCell(0);
                // 员工姓名
                cell0.setCellValue(employeeWorkTime.getName());
                cell0.setCellStyle(dataStyle);
                // 员工加班日期
                Cell cell1 = row.createCell(1);
                cell1.setCellValue(DateUtil.format(
                        employeeWorkTime.getWorkDate(), "yyyy.MM.dd")
                );
                cell1.setCellStyle(dataStyle);
                // 员工加班时间点（开始时间-结束时间）
                Cell cell2 = row.createCell(2);
                cell2.setCellValue(DateUtil.getTime(employeeWorkTime.getBeginTime())
                        + "-" + DateUtil.getTime(employeeWorkTime.getEndTime()));
                cell2.setCellStyle(dataStyle);
                // 计算时长
                Cell cell3 = row.createCell(3);
                cell3.setCellValue("有效加班时长" + overtime + "小时");
                cell3.setCellStyle(dataStyle);
                rowIndex++;

            }//end for

        } // end for

        // 设置自动调整列宽度
        sheet.autoSizeColumn(0);
        sheet.autoSizeColumn(1);
        sheet.autoSizeColumn(2);
        sheet.autoSizeColumn(3);
        sheet.autoSizeColumn(4);
        sheet.autoSizeColumn(5);

        FileOutputStream fileOut = new FileOutputStream(this.filename);
        wb.write(fileOut);
        fileOut.close();

    }

}
